package regex

import (
	"math/big"

	textker "gitee.com/endlesstravel/goylc/textker"
)

// #
// b
// \b ???
// []
// (?<ffff>fadsf)
// (?'ffff'fadsf)
// (fadsf)
// (fadsf)
// (fadsf)|dfsdfsdf
// parrent to tree
func buildRegexTree(tw *textker.TextWalker) *regexTree {
	tw.SetPos(tw.GetLen() - 1) // last
	root := buildRegexTreeNode(tw)
	return &regexTree{
		Root: root,
	}
}

func buildRegexTreeNode_backslash(tw *textker.TextWalker) *regexTreeNode {
	tw.MoveNextRune()
	if !tw.HasNext() {
		panic("ERROR : \\ 字符后不存在字符")
	}
	nextChar := tw.PeekNextRune()
	switch nextChar {

	case _CONST_d_RUNE: // \d 匹配 0-9
		fallthrough
	case _CONST_D_RUNE: //  \D 匹配非 0-9
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:          REGEX_TREE_NODE_ALPHA_SET,
			ResultReverse: nextChar == _CONST_D_RUNE,
			AlphaRangeSet: makeRegexAlphaRangeSetRangeSet(_CONST_0_RUNE, _CONST_9_RUNE),
		}

	case _CONST_w_RUNE: // \w 匹配包括下划线、字母和数字的字符的任一字符。
		fallthrough
	case _CONST_W_RUNE: // \w 匹配除下划线、字母和数字的字符的任一字符
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:          REGEX_TREE_NODE_ALPHA_SET,
			ResultReverse: nextChar == _CONST_W_RUNE,
			AlphaRangeSet: []regexAlphaRangeSet{
				makeRegexAlphaRangeSetRange(_CONST_a_RUNE, _CONST_z_RUNE),
				makeRegexAlphaRangeSetRange(_CONST_A_RUNE, _CONST_Z_RUNE),
				makeRegexAlphaRangeSetRange(_CONST_0_RUNE, _CONST_9_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_UNDERLINE_RUNE),
			},
		}

	case _CONST_s_RUNE: // \s 匹配空白字符。包括空格、制表符、换页符等。等价于[ \f\n\r\t\v]。
		fallthrough
	case _CONST_S_RUNE: // \S 匹配除空白外的字符
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:          REGEX_TREE_NODE_ALPHA_SET,
			ResultReverse: nextChar == _CONST_S_RUNE,
			AlphaRangeSet: []regexAlphaRangeSet{
				makeRegexAlphaRangeSetOne(_CONST_SKPACE_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_FF_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_LF_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_CR_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_TAB_RUNE),
				makeRegexAlphaRangeSetOne(_CONST_VT_RUNE),
			},
		}

	case _CONST_n_RUNE: // \n 匹配回车符（ LF，NL ）
		fallthrough
	case _CONST_N_RUNE: // \N 匹配除回车符外的字符
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:          REGEX_TREE_NODE_ALPHA,
			ResultReverse: nextChar == _CONST_N_RUNE,
			FirstAlpha:    _CONST_LF_RUNE,
		}

	case _CONST_r_RUNE: // \r 匹配换行符
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: _CONST_CR_RUNE,
		}

	case _CONST_t_RUNE: // \t 匹配 tab 符
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: _CONST_TAB_RUNE,
		}

	case _CONST_f_RUNE: // \f 匹配一个换页符。等价于\x0c 和\cL。
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: _CONST_FF_RUNE,
		}

	case _CONST_v_RUNE: // \v 匹配一个垂直制表符。等价于\x0b 和\cK。
		tw.MoveNextRune()
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: _CONST_VT_RUNE,
		}

	case _CONST_u_RUNE: // \u Unicode代码中十六进制代码为nnnn的字符
		if !tw.HasNextCount(5) {
			panic("非法的正则表达式： 位置 \\u ")
		}
		tw.MoveNextRune() // u
		hex_str := string([]rune{
			tw.MoveNextRune(),
			tw.MoveNextRune(),
			tw.MoveNextRune(),
			tw.MoveNextRune(),
		})
		theBigNumber := new(big.Int)
		theBigNumber.SetString(hex_str, 16)
		theNumber := theBigNumber.Int64()
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: rune(theNumber),
		}

	case _CONST_b_RUNE: //  \b 匹配一个单词边界
		fallthrough
	case _CONST_B_RUNE: //  \B 匹配非单词边界
		return &regexTreeNode{
			Type:          REGEX_TREE_NODE_BOUND,
			ResultReverse: nextChar == _CONST_B_RUNE,
		}

	default: // \b \[  \a // 保持原样
		return &regexTreeNode{
			Type:       REGEX_TREE_NODE_ALPHA,
			FirstAlpha: nextChar,
		}
	}

}

// 后缀表达式，将由后向前匹配
func buildRegexTreeNode(tw *textker.TextWalker) *regexTreeNode {
	if tw.HasNext() {
		theCurrentChar := tw.PeekNextRune()

		switch theCurrentChar {
		// 特殊字符  \b \a ...
		case _CONST_BACKSLASH_RUNE:
			return buildRegexTreeNode_backslash(tw)

		case _CONST_DOT_RUNE: // .
			return &regexTreeNode{
				Type: REGEX_TREE_NODE_DOT,
			}
		case _CONST_CARET_RUNE: // ^
			return &regexTreeNode{
				Type: REGEX_TREE_NODE_BEGIN,
			}
		case _CONST_DOLLAR_RUNE: // $
			return &regexTreeNode{
				Type: REGEX_TREE_NODE_END,
			}

		case _CONST_L_MID_BRACKET_RUNE: // [....]
			fallthrough
		case _CONST_R_MID_BRACKET_RUNE:
			panic("TODO")

		case _CONST_L_BRACKET_RUNE: // (....)
			fallthrough
		case _CONST_R_BRACKET_RUNE:
			panic("TODO")

		case _CONST_L_BIG_BRACKET_RUNE: // {....}
			fallthrough
		case _CONST_R_BIG_BRACKET_RUNE: // }
			panic("TODO")

		case _CONST_V_LINE_RUNE: // |
			panic("TODO1")

		case _CONST_QUESTION_RUNE: // ?
			fallthrough
		case _CONST_STAR_RUNE: // *
			fallthrough
		case _CONST_ADD_RUNE: // +
			panic("TODO")

		default:
			return &regexTreeNode{
				Type:       REGEX_TREE_NODE_ALPHA,
				FirstAlpha: theCurrentChar,
			}

		}

	}

	return nil
}

//
//
//
//

// 下面是词法
// thunk       [sdfsdf]   a     b   . ^ $  \h d
// lb (         (  (?<fff>    (?'xxxx'
// rb )         )
// siffix      * ? + {m,n}

// 下面是具体推导式
// ALL  →  EXP
// EXP  →  ( EXP )
// EXP  →  EXP siffix
// EXP  →  EXP | EXP
// EXP  →  thunk
// EXP  →  thunk PPP
// PPP  →  EXP
// PPP  →  e
